package designpatterns.singleton;

/**
 * 懒加载，单例模式
 *
 * @author miweidong
 * @date 2021-09-16 15:13
 */
public class Singleton {

    /**
     * 懒汉实例
     * volatile是为了防止jvm底层的操作指令重排序，而导致的线程并发问题
     */
    private static volatile Singleton instance;

    /**
     * 构造方法私有化
     */
    private Singleton() {
    }

    /**
     * 获取对象实例  目的是只有首次加载对象，后续请求，直接返回第一次初始化后的对象
     *
     * @return 对象实例
     */
    public static Singleton getInstance() {
        // 外层判断为了防止多线程请求加载同步代码块，导致排队堵塞
        // 如果没有外层判断，第一次以后的每次调用方法，都需要加锁和释放锁
        if (instance == null) {
            synchronized (Singleton.class) {
                // 内层判断，防止多个线程，创建多个实例
                // 如果没有内层判断，假如两个线程，同时到达加锁代码块，其中一个执行完，释放锁，此时，单例对象已经被创建，
                // 另一个线程，进来，不判断，又创建了一个对象，这不符合单例要求
                if (instance == null) {
                    // new对象操作是一组jvm指令，会发生重排序
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
